type EEventList = Function[]
interface IEvent {
  [key: string]: EEventList
}
export class EventEmitter {
  _eventList: IEvent = {}
  constructor() {
  }
  getEventList(name: string): EEventList {
    if (!this._eventList[name]) {
      this._eventList[name] = []
    }
    return this._eventList[name]
  }
  $on(eventName: string, callback: Function) {
    if (!this._eventList[eventName]) {
      this._eventList[eventName] = []
    }
    this._eventList[eventName].push(callback)
  }
  $once(eventName: string, callback: Function) {
    const onceCallback = (...args: any[]) => {
      callback(...args)
      this.$off(eventName, onceCallback)
    }
    this.$on(eventName, onceCallback)
  }
  $emit(eventName: string, ...args: any[]) {
    if (this._eventList[eventName]) {
      this._eventList[eventName].forEach(callback => {
        callback(...args)
      })
    }
  }
  $off(eventName: string, callback: Function) {
    if (this._eventList[eventName]) {
      this._eventList[eventName] = this._eventList[eventName].filter(item => item !== callback)
    }
  }
}